package com.edt.ichannel.api.service.impl;

import cc.edt.iceutils2.string.IceStringUtils;
import cc.edt.iceutils3.date.IceDateOperationUtils;
import cc.edt.iceutils3.json.IceFastJsonUtils;
import cc.edt.iceutils3.random.IceIdGenerateUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.edt.ichannel.api.common.constant.CommonConstant;
import com.edt.ichannel.api.common.entity.ActionResult;

import com.edt.ichannel.api.dao.BFDao;
import com.edt.ichannel.api.entiy.local.ContinueCommissionRule;
import com.edt.ichannel.api.entiy.local.OrderChannel;
import com.edt.ichannel.api.entiy.local.OrderCreditBf;
import com.edt.ichannel.api.entiy.local.EntityForKafka;
import com.edt.ichannel.api.entiy.local.EntityForSanHuResult;
import com.edt.ichannel.api.service.*;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class BFServiceImpl implements BFService {
    @Resource
    private ContinueCommissionRuleService continueCommissionRuleService;
    @Resource
    private OrderChannelService orderChannelService;
    @Resource
    private EdtApiService edtApiService;
    @Resource
    private FirstmoneyLogService firstmoneyLogService;
    @Resource
    private OrderCreditBfService orderCreditBfService;
    @Resource
    private PutoutCommissionService putoutCommissionService;
    @Resource
    private MerchantService merchantService;

    @Resource
    private BFDao bfDao;

    @Override
    public List<ContinueCommissionRule> getAllContinueCommissionRules() {
        return continueCommissionRuleService.getAllContinueCommissionRules();
    }

    @Override
    public List<OrderChannel> getNeedBFOrder(String cityCode, int continuitionDay, String productId, String typeStr) {
        return orderChannelService.getNeedBFOrder(cityCode, continuitionDay, productId,  typeStr);
    }

    @Override
    public EntityForSanHuResult getSanHuInfoByServiceCode(String serviceCode) {
        EntityForSanHuResult entityForSanHuResult = new EntityForSanHuResult();
        ActionResult result = edtApiService.sanHu(serviceCode,CommonConstant.INFOLIST_USER);
        if (result.isSuccess()) {
            String userInfo = JSONObject.parseObject((String)result.getResultList()).getString(CommonConstant.KEY_USERINFO);
            if(IceStringUtils.isNotBlank(userInfo)){
                entityForSanHuResult = JSON.parseObject(userInfo,EntityForSanHuResult.class);
            }
            entityForSanHuResult.setSuccess(true);

        }else{
            if(result.getResultList() != null){
                String json = (String)result.getResultList();
                entityForSanHuResult = JSON.parseObject(json,EntityForSanHuResult.class);
                entityForSanHuResult.setRemark(json);
            }

            entityForSanHuResult.setSuccess(false);
        }
        return entityForSanHuResult;
    }

    @Override
    public boolean hasUserId(String orderCode, String serviceCode, String userid) {
        int count = firstmoneyLogService.selectUserIdCount(orderCode,serviceCode,userid);
        log.info("三户返回信息userid 在本地存在个数："+count);
        return count > 0;
    }

    @Override
    public boolean validateIsOnline(String orderCode, String serviceCode) {
        EntityForSanHuResult entityForSanHuResult = getSanHuInfoByServiceCode(serviceCode);
        log.info("三户解析结果："+IceFastJsonUtils.toJsonString(entityForSanHuResult));
        if(entityForSanHuResult.isSuccess()) {
            return hasUserId(orderCode, serviceCode, entityForSanHuResult.getUserId());
        }else{
            return false;
        }
    }

    @Override
    public boolean hasProductId(String serviceCode, String productCode, String productid) {
        //根据 号码查询地市中文名
        String cityName = bfDao.selectCityNameByServiceCode(serviceCode);
        //根据中文名查询接口查询编码
        String numCityCode = edtApiService.getCityCodeByName(cityName);
        //根据产品编码查询产品id
        String worpProductId = bfDao.selectProductIdByProductCode(productCode);
        //根据产品id 地市编码 三户产品id 查询产品包数据，如果有返回true
        int count = bfDao.selectProductPackageCount(worpProductId,numCityCode,productid);
        log.info("三户返回信息product 在本地存在个数："+count);
        return count > 0;
    }

    @Override
    @Transactional
    public void computContinueCommission(OrderChannel orderChannel,ContinueCommissionRule continueCommissionRule) {
        if(orderChannel != null){
            OrderCreditBf orderCreditBf = new OrderCreditBf();
            BeanUtils.copyProperties(orderChannel,orderCreditBf,"id");
            orderCreditBf.setId(IceIdGenerateUtils.toSerialCode(32));
            orderCreditBf.setState(CommonConstant.FLOW_NOT_OVER);
            orderChannelService.setExpansionTypeAndLevl(orderCreditBf);
            if(orderChannel.getSettletType() != null){
                if(CommonConstant.SETTLET_TYPE_YJ_STR.equals(orderChannel.getSettletType())){
                    orderCreditBf.setState(CommonConstant.FLOW_OVER);
                    orderCreditBf.setRemark("bf 权益月结订单");
                }
            }else{
                Integer settletType = merchantService.selectSettletTypeByExapnsionId(orderCreditBf.getChannelId());
                if(CommonConstant.STAFF_TYPE_QIANY == orderCreditBf.getChannelType() && settletType != null
                        && settletType.equals(CommonConstant.SETTLET_TYPE_YJ) ){
                    orderCreditBf.setState(CommonConstant.FLOW_OVER);
                    orderCreditBf.setRemark("bf 权益月结订单");
                }
            }
            if(CommonConstant.FLOW_NOT_OVER == orderCreditBf.getState()){
                OrderCreditBf orderCreditBfOld = orderCreditBfService.selectNewestData(orderCreditBf.getOrderCode());
//                ●remove_tag为0且user_state_codeset 为0表示用户正常在网计算佣金
//                ●remove_tag不等于0表示用户销户，在网补发流程结束，后续也不需要再查询计算佣金
//                ●remove_tag为0且user_state_codeset不等于0表示用户欠费，当日不结算佣金，次日继续查询，
//                连续查询30天（从当日开始算30天，例如3月1日满足在网时间但用户欠费，则持续查询至3月30日），
//                当查询结果为remove_tag为0且user_state_codeset 为0表示用户正常在网，按照正常在网时的佣金规则计算在网佣金金额；
//                若连续查询30天用户仍处于欠费状态，则不再查询，不结算在网佣金。
                switch (validateNeedComput(orderCreditBf,orderChannel.getDevelopStaffId())){
                    case CommonConstant.KFK_VALIDATE_RESULT_ZC:
                        saveOrUpdateSuccess(orderCreditBf,continueCommissionRule,orderCreditBfOld);
                        break;
                    case CommonConstant.KFK_VALIDATE_RESULT_XH:
                        saveOrUpdateXh(orderCreditBf,orderCreditBfOld);
                        break;
                    case CommonConstant.KFK_VALIDATE_RESULT_QF:
                        saveOrUpdateQf(orderCreditBf,orderCreditBfOld);
                        break;
                    case CommonConstant.KFK_VALIDATE_RESULT_WZ:
                        saveError(orderCreditBf,orderCreditBfOld);
                        break;
                    case CommonConstant.KFK_VALIDATE_RESULT_UDVFAIL:
                        saveValidateUseridOrDevCodeFail(orderCreditBf,orderCreditBfOld);
                        break;
                }
            }

        }
    }

    @Override
    public int validateNeedComput(OrderCreditBf orderCreditBf,String developStaffId) {
        if(orderCreditBf == null) {
            return CommonConstant.KFK_VALIDATE_RESULT_UDVFAIL;
        }
        //调接口
        ActionResult result = edtApiService.selectFirstMoneyInfo(orderCreditBf.getServiceCode(),orderCreditBf.getOrderCode(),orderCreditBf.getOrderDate());
        log.info("中控返回："+IceFastJsonUtils.toJsonString(result));
        orderCreditBf.setRemark("kfk返回："+result.getResultList());
        String userId = bfDao.selectUserIdByOrderCode(orderCreditBf.getOrderCode());
        orderCreditBf.setUserId(userId);
        String userIdKfk = null;
        String developStaffIdKfk = null;
        String removeTag = null;
        String userStateCodeset = null;
        if(result.getResultList() != null){
            EntityForKafka returnInfo = JSON.parseObject((String)result.getResultList() ,EntityForKafka.class);
            if(returnInfo != null && returnInfo.getUNI_BSS_INFO() != null ){
                userIdKfk = returnInfo.getUNI_BSS_INFO().getUSER_ID();
                developStaffIdKfk = returnInfo.getUNI_BSS_INFO().getDEVELOP_STAFF_ID();
                removeTag = returnInfo.getUNI_BSS_INFO().getREMOVE_TAG();
                userStateCodeset = returnInfo.getUNI_BSS_INFO().getUSER_STATE_CODESET();
                orderCreditBf.setUserIdNew(userIdKfk);
                orderCreditBf.setDevelopStaffIdNew(developStaffIdKfk);
                orderCreditBf.setDevelopStaffId(developStaffId);
                orderCreditBf.setRemoveTag(removeTag);
                orderCreditBf.setUserStateCodeset(userStateCodeset);
                if(IceStringUtils.isNotBlank(userIdKfk)){
                    if(IceStringUtils.isBlank(userId)){
                        orderCreditBf.setRemark("查询订单userid 为空 "+orderCreditBf.getOrderCode());
                    }else{
                        result = edtApiService.validateUserId(orderCreditBf.getServiceCode(),orderCreditBf.getOrderCode(),orderCreditBf.getOrderDate(),userId,userIdKfk);
                        if(result.isSuccess()){
                            if(IceStringUtils.isAnyBlank(developStaffId,developStaffIdKfk)){
                                orderCreditBf.setRemark("发展人编码有空 下单 developStaffId "+developStaffId+"developStaffId "+developStaffIdKfk+"单号"+orderCreditBf.getOrderCode());
                            }else{
                                result = edtApiService.validateDevCode(orderCreditBf.getServiceCode(),orderCreditBf.getOrderCode(),orderCreditBf.getOrderDate(),developStaffId,developStaffIdKfk);
                                if(result.isSuccess()){
                                    return edtApiService.validateOnlineState(orderCreditBf.getServiceCode(),orderCreditBf.getOrderCode(),orderCreditBf.getOrderDate(),removeTag,userStateCodeset);
                                }else{
                                    orderCreditBf.setRemark("发展人编码验证失败 下单 developStaffId "+developStaffId+"developStaffId "+developStaffIdKfk+"单号"+orderCreditBf.getOrderCode());
                                }
                            }

                        }else{
                            orderCreditBf.setRemark("userid不一致 下单 userid "+userId+"本次查询userid "+userIdKfk+"单号"+orderCreditBf.getOrderCode());
                        }
                    }

                }else{
                    orderCreditBf.setRemark("kafk接口查询userid 为空"+orderCreditBf.getOrderCode());
                }
                return CommonConstant.KFK_VALIDATE_RESULT_UDVFAIL;
            }

        }
        return CommonConstant.KFK_VALIDATE_RESULT_WZ;
    }



    /**
     * 计算成功，保存数据,流程结束
     * @param orderCreditBf 补发信息
     * @param continueCommissionRule 规则信息
     */
    private void saveOrUpdateSuccess(OrderCreditBf orderCreditBf,ContinueCommissionRule continueCommissionRule,OrderCreditBf orderCreditBfOld){
        if(orderCreditBfOld == null){
            orderCreditBf.setCommissionMoney(continueCommissionRule.getCommissionMoney());
            orderCreditBf.setState(CommonConstant.FLOW_OVER);
            orderCreditBf.setRemark("计算成功");
            orderCreditBf.setProductId(continueCommissionRule.getProductId());
            orderCreditBf.setContinuitionDay(continueCommissionRule.getContinuitionDay());
            Date date = new Date();
            orderCreditBf.setAddTime(date);
            orderCreditBf.setUpdateDate(date);
            //入库
            orderCreditBfService.saveOrderCreditBf(orderCreditBf);
        }else{
            orderCreditBfOld.setUserId(orderCreditBf.getUserId());
            orderCreditBfOld.setUserIdNew(orderCreditBf.getUserIdNew());
            orderCreditBfOld.setDevelopStaffId(orderCreditBf.getDevelopStaffId());
            orderCreditBfOld.setDevelopStaffIdNew(orderCreditBf.getDevelopStaffIdNew());
            orderCreditBfOld.setRemoveTag(orderCreditBf.getRemoveTag());
            orderCreditBfOld.setUserStateCodeset(orderCreditBf.getUserStateCodeset());
            orderCreditBfOld.setCommissionMoney(continueCommissionRule.getCommissionMoney());
            orderCreditBfOld.setState(CommonConstant.FLOW_OVER);
            orderCreditBfOld.setRemark("计算成功");
            orderCreditBfOld.setUpdateDate(new Date());
            orderCreditBfOld.setProductId(continueCommissionRule.getProductId());
            orderCreditBfOld.setContinuitionDay(continueCommissionRule.getContinuitionDay());
            orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
        }

    }

    /**
     * 号码销户 不计算，流程刚结束保存信息
     */
    private void saveOrUpdateXh(OrderCreditBf orderCreditBf,OrderCreditBf orderCreditBfOld){
        if(orderCreditBfOld == null){
            orderCreditBf.setRemark("号码已经离网 ："+orderCreditBf.getServiceCode());
            orderCreditBf.setState(CommonConstant.FLOW_OVER);
            Date date = new Date();
            orderCreditBf.setAddTime(date);
            orderCreditBf.setUpdateDate(date);
            //入库
            orderCreditBfService.saveOrderCreditBf(orderCreditBf);
        }else{
            orderCreditBfOld.setUserId(orderCreditBf.getUserId());
            orderCreditBfOld.setUserIdNew(orderCreditBf.getUserIdNew());
            orderCreditBfOld.setDevelopStaffId(orderCreditBf.getDevelopStaffId());
            orderCreditBfOld.setDevelopStaffIdNew(orderCreditBf.getDevelopStaffIdNew());
            orderCreditBfOld.setRemoveTag(orderCreditBf.getRemoveTag());
            orderCreditBfOld.setUserStateCodeset(orderCreditBf.getUserStateCodeset());
            orderCreditBfOld.setRemark("号码已经离网 ："+orderCreditBf.getServiceCode());
            orderCreditBfOld.setState(CommonConstant.FLOW_OVER);
            orderCreditBfOld.setUpdateDate(new Date());
            //入库
            orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
        }

    }

    /**
     * 欠费，连续查30天
     * 之后失败数据只会有一条
     * 即修改之前每条失败都即一条记录的流程
     */
    private void saveOrUpdateQf(OrderCreditBf orderCreditBf,OrderCreditBf orderCreditBfOld){

        if(orderCreditBfOld == null){
            orderCreditBf.setRemark("号码已经欠费 ："+orderCreditBf.getServiceCode());
            orderCreditBf.setState(CommonConstant.FLOW_NOT_OVER);
            orderCreditBf.setSelectEndDate(IceDateOperationUtils.addDays(orderCreditBf.getAddTime(),29));
            Date date = new Date();
            orderCreditBf.setAddTime(date);
            orderCreditBf.setUpdateDate(date);
            orderCreditBfService.saveOrderCreditBf(orderCreditBf);
        }else{
            orderCreditBfOld.setUserId(orderCreditBf.getUserId());
            orderCreditBfOld.setUserIdNew(orderCreditBf.getUserIdNew());
            orderCreditBfOld.setDevelopStaffId(orderCreditBf.getDevelopStaffId());
            orderCreditBfOld.setDevelopStaffIdNew(orderCreditBf.getDevelopStaffIdNew());
            orderCreditBfOld.setRemoveTag(orderCreditBf.getRemoveTag());
            orderCreditBfOld.setUserStateCodeset(orderCreditBf.getUserStateCodeset());
            if(orderCreditBfOld.getSelectEndDate() == null){
                orderCreditBfOld.setRemark("号码已经欠费 ："+orderCreditBf.getServiceCode());
                orderCreditBfOld.setState(CommonConstant.FLOW_NOT_OVER);
                orderCreditBfOld.setSelectEndDate(IceDateOperationUtils.addDays(orderCreditBf.getAddTime(),29));
                orderCreditBfOld.setUpdateDate(new Date());
                orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
            }else{
                if(IceDateOperationUtils.isSameDay(new Date(),orderCreditBfOld.getSelectEndDate()) ||
                        IceDateOperationUtils.isAfter(new Date(),orderCreditBfOld.getSelectEndDate())  ){
                    orderCreditBfOld.setRemark("号码已经欠费 ："+orderCreditBfOld.getServiceCode()+"已经连续查询30天");
                    orderCreditBfOld.setState(CommonConstant.FLOW_OVER);
                    orderCreditBfOld.setUpdateDate(new Date());
                    orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
                }else{
                    orderCreditBfOld.setUpdateDate(new Date());
                    orderCreditBfOld.setRemark("号码已经欠费 ："+orderCreditBf.getServiceCode());
                    orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
                }
            }
        }
    }
    /**
     * 查询接口异常，继续查询
     * 之后失败数据只会有一条
     * 即修改之前每条失败都即一条记录的流程
     */
    private void saveError(OrderCreditBf orderCreditBf,OrderCreditBf orderCreditBfOld){

        if(orderCreditBfOld == null){
            orderCreditBf.setState(CommonConstant.FLOW_NOT_OVER);
            Date date = new Date();
            orderCreditBf.setAddTime(date);
            orderCreditBf.setUpdateDate(date);
            orderCreditBfService.saveOrderCreditBf(orderCreditBf);
        }else{
            orderCreditBfOld.setUserId(orderCreditBf.getUserId());
            orderCreditBfOld.setUserIdNew(orderCreditBf.getUserIdNew());
            orderCreditBfOld.setDevelopStaffId(orderCreditBf.getDevelopStaffId());
            orderCreditBfOld.setDevelopStaffIdNew(orderCreditBf.getDevelopStaffIdNew());
            orderCreditBfOld.setRemoveTag(orderCreditBf.getRemoveTag());
            orderCreditBfOld.setUserStateCodeset(orderCreditBf.getUserStateCodeset());
            orderCreditBfOld.setUpdateDate(new Date());
            orderCreditBfOld.setState(CommonConstant.FLOW_NOT_OVER);
            orderCreditBfOld.setRemark(orderCreditBf.getRemark());
            orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
        }
    }

    /**
     * 查询接口异常，继续查询
     * 之后失败数据只会有一条
     * 即修改之前每条失败都即一条记录的流程
     */
    private void saveValidateUseridOrDevCodeFail(OrderCreditBf orderCreditBf,OrderCreditBf orderCreditBfOld){

        if(orderCreditBfOld == null){
            orderCreditBf.setState(CommonConstant.FLOW_OVER);
            Date date = new Date();
            orderCreditBf.setAddTime(date);
            orderCreditBf.setUpdateDate(date);
            orderCreditBfService.saveOrderCreditBf(orderCreditBf);
        }else{
            orderCreditBfOld.setUserId(orderCreditBf.getUserId());
            orderCreditBfOld.setUserIdNew(orderCreditBf.getUserIdNew());
            orderCreditBfOld.setDevelopStaffId(orderCreditBf.getDevelopStaffId());
            orderCreditBfOld.setDevelopStaffIdNew(orderCreditBf.getDevelopStaffIdNew());
            orderCreditBfOld.setRemoveTag(orderCreditBf.getRemoveTag());
            orderCreditBfOld.setRemark(orderCreditBf.getRemark());
            orderCreditBfOld.setUserStateCodeset(orderCreditBf.getUserStateCodeset());
            orderCreditBfOld.setUpdateDate(new Date());
            orderCreditBfOld.setState(CommonConstant.FLOW_OVER);
            orderCreditBfService.updateOrderCreditBf(orderCreditBfOld);
        }
    }
    @Override
    public List<OrderCreditBf> getAllNeedPutOut() {
        return orderCreditBfService.getAllNeedPutOut();
    }

    @Override
    public void putOutCommissionBf(OrderCreditBf orderCreditBf) {
        putoutCommissionService.putoutCommissionBf(orderCreditBf);
    }

}
